import JSZip = require("jszip");
export default class ZipAssetManager {
    static zipPool: Map<string, JSZip> = new Map();
    static filePool: Map<string | URL, JSZip.JSZipObject> = new Map();
    static unzipedCache = new Map<string, any>();

    static normalReqCount = 0;
    static zipReqCount = 0;
};


function hackXMLHttpRequest() {

    const accessor = Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype, 'response');
    Object.defineProperty(XMLHttpRequest.prototype, 'response', {
        get: function () {
            if (this.zipCacheUrl) {
                const res = ZipAssetManager.unzipedCache.get(this.zipCacheUrl);
                return this.responseType === "json"
                    ? JSON.parse(res)
                    : res;
            }
            return accessor.get.call(this);
        },
        set: function (str) {
            // console.log('set responseText: %s', str);
            // return accessor.set.call(this, str);
        },
        configurable: true
    });


    // 拦截open
    const oldOpen = XMLHttpRequest.prototype.open;
    // @ts-ignore
    XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
        // 有这个资源就记录下来
        if (ZipAssetManager.filePool.has(url)) {
            this.zipCacheUrl = url;
        }
        return oldOpen.apply(this, arguments);
    }

    // 拦截send
    const oldSend = XMLHttpRequest.prototype.send;
    XMLHttpRequest.prototype.send = async function (data) {
        if (this.zipCacheUrl) {
            // 有缓存就不解析了
            if (!ZipAssetManager.unzipedCache.has(this.zipCacheUrl)) {

                const file = ZipAssetManager.filePool.get(this.zipCacheUrl);

                if (this.responseType === "json") {
                    const text = await file.async("text");
                    ZipAssetManager.unzipedCache.set(this.zipCacheUrl, text);
                } else {
                    // 直接拿cocos设置的responseType给zip解析
                    const res = await file.async(this.responseType);
                    ZipAssetManager.unzipedCache.set(this.zipCacheUrl, res);
                }
            }

            // 解析完了直接调用onload，并且不再发起真实的网络请求
            this.onload();
            ZipAssetManager.zipReqCount++;
            console.log("zip优化加载:", ZipAssetManager.zipReqCount);
            return;
        }
        ZipAssetManager.normalReqCount++;
        // console.log("普通加载:", ZipAssetManager.normalReqCount);

        return oldSend.apply(this, arguments);
    }
}

// hackXMLHttpRequest();